package com.amado.course35Concurrent;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class CompletableFutureTest {
    static AtomicInteger count = new AtomicInteger();
    //推荐使用自己的线程池也方便定位问题，TRACE_ID跟踪
    static final ThreadPoolExecutor NOTICE_MESSAGE_POOL =
            new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
                    (r) -> new Thread(r, "触发通知消息线程" + count.getAndIncrement()), new ThreadPoolTest.NoticeMessageDiscardPolicy());
    public static void main(String[] args) {


        final List<Throwable> throwableList = new ArrayList<>();
        final List<String> list = new ArrayList<>();
        CompletableFuture oneCompletableFuture = CompletableFuture.runAsync(() -> {
            list.add(new Date().toString());
            System.out.println(Thread.currentThread().getName() + new Date());
        }, NOTICE_MESSAGE_POOL);
        CompletableFuture twoCompletableFuture = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(2000);
                if(new Random().nextBoolean()){
                    throw new IllegalArgumentException("参数错误");
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + new Date());
            list.add(new Date().toString());

        }, NOTICE_MESSAGE_POOL);

        CompletableFuture.allOf(oneCompletableFuture, twoCompletableFuture).exceptionally(e->{
            throwableList.add(e.getCause());
            return null;
        }).join();

        if(!throwableList.isEmpty()){
            throwableList.forEach(throwable -> {
                if (throwable instanceof IllegalArgumentException) {
                    throw (IllegalArgumentException) throwable;
                }
            });
        }

        System.out.println(Thread.currentThread().getName() + list + new Date());
    }
}
